InĀ [1]:
import vectorbt as vbt
vbt.settings['plotting']['use_widgets'] = False
data_exchange = 'binanceusdm'
data_timeframe = '1h'
data_start = '2023-01-01'
data_end = '2023-08-31'
bband_sma = 20
bband_std = 2
bband_bandwidth_thr = 0.015 # max 0.22
InĀ [2]:
btc_price = vbt.CCXTData.download_symbol('BTC/USDT', exchange=data_exchange, timeframe=data_timeframe, start=data_start, end=data_end)
eth_price = vbt.CCXTData.download_symbol('ETH/USDT', exchange=data_exchange, timeframe=data_timeframe, start=data_start, end=data_end)
InĀ [3]:
btc_price['btc_eth'] = btc_price['Close'] / eth_price['Close']
bband = vbt.BBANDS.run(btc_price['btc_eth'], window=bband_sma, alpha=bband_std)
btc_price['bandwidth'] = bband.bandwidth
btc_price['bandwidth'].fillna(0.0, inplace=True)
bband.plot().show()
InĀ [4]:
bband.bandwidth[bband.bandwidth > bband_bandwidth_thr]
bband.bandwidth.mean()
Out[4]:
0.01414273015840736
InĀ [5]:
# long BTC short ETH, close at middle
btc_price['upper_crossed_above'] = bband.upper_crossed_above(btc_price['btc_eth']) & (btc_price['bandwidth'] > bband_bandwidth_thr)
btc_price['middle_crossed_below'] = bband.middle_crossed_below(btc_price['btc_eth'])
InĀ [6]:
entries = btc_price['upper_crossed_above']
exits = btc_price['middle_crossed_below']
pf = vbt.Portfolio.from_signals(btc_price['Close'], entries, exits, max_size=1, init_cash=100000)
pf.plot().show()
InĀ [7]:
pf.stats()
Out[7]:
Start 2022-12-31 16:00:00+00:00 End 2023-08-30 15:00:00+00:00 Period 242 days 00:00:00 Start Value 100000.0 End Value 106596.7 Total Return [%] 6.5967 Benchmark Return [%] 63.84671 Max Gross Exposure [%] 29.172944 Total Fees Paid 0.0 Max Drawdown [%] 2.482099 Max Drawdown Duration 124 days 21:00:00 Total Trades 49 Total Closed Trades 49 Total Open Trades 0 Open Trade PnL 0.0 Win Rate [%] 59.183673 Best Trade [%] 10.14753 Worst Trade [%] -4.172992 Avg Winning Trade [%] 2.125024 Avg Losing Trade [%] -1.572093 Avg Winning Trade Duration 1 days 04:35:10.344827586 Avg Losing Trade Duration 0 days 18:57:00 Profit Factor 1.760891 Expectancy 134.626531 Sharpe Ratio 1.643291 Calmar Ratio 4.075021 Omega Ratio 1.1327 Sortino Ratio 2.427583 dtype: object
InĀ [8]:
pf = vbt.Portfolio.from_signals(eth_price['Close'], short_entries=entries, short_exits=exits, size=btc_price['btc_eth'], init_cash=100000)
pf.plot().show()
InĀ [9]:
pf.stats()
Out[9]:
Start 2022-12-31 16:00:00+00:00 End 2023-08-30 15:00:00+00:00 Period 242 days 00:00:00 Start Value 100000.0 End Value 92938.777384 Total Return [%] -7.061223 Benchmark Return [%] 41.613652 Max Gross Exposure [%] 0.0 Total Fees Paid 0.0 Max Drawdown [%] 8.86361 Max Drawdown Duration 229 days 02:00:00 Total Trades 49 Total Closed Trades 49 Total Open Trades 0 Open Trade PnL 0.0 Win Rate [%] 40.816327 Best Trade [%] 6.822715 Worst Trade [%] -10.487001 Avg Winning Trade [%] 1.760837 Avg Losing Trade [%] -2.26195 Avg Winning Trade Duration 0 days 21:57:00 Avg Losing Trade Duration 1 days 02:31:02.068965517 Profit Factor 0.576127 Expectancy -144.106584 Sharpe Ratio -1.55367 Calmar Ratio -1.179745 Omega Ratio 0.888626 Sortino Ratio -2.098598 dtype: object
InĀ [10]:
# long ETH short BTC, close at middle
btc_price['lower_crossed_below'] = bband.lower_crossed_below(btc_price['btc_eth']) & (btc_price['bandwidth'] > bband_bandwidth_thr)
btc_price['middle_crossed_above'] = bband.middle_crossed_above(btc_price['btc_eth'])
InĀ [11]:
entries = btc_price['lower_crossed_below']
exits = btc_price['middle_crossed_above']
pf = vbt.Portfolio.from_signals(eth_price['Close'], entries, exits, size=btc_price['btc_eth'], init_cash=100000)
pf.plot().show()
InĀ [12]:
pf.stats()
Out[12]:
Start 2022-12-31 16:00:00+00:00 End 2023-08-30 15:00:00+00:00 Period 242 days 00:00:00 Start Value 100000.0 End Value 103114.675182 Total Return [%] 3.114675 Benchmark Return [%] 41.613652 Max Gross Exposure [%] 31.03942 Total Fees Paid 0.0 Max Drawdown [%] 3.968904 Max Drawdown Duration 138 days 09:00:00 Total Trades 41 Total Closed Trades 41 Total Open Trades 0 Open Trade PnL 0.0 Win Rate [%] 46.341463 Best Trade [%] 12.235572 Worst Trade [%] -5.265773 Avg Winning Trade [%] 3.359557 Avg Losing Trade [%] -2.046006 Avg Winning Trade Duration 1 days 10:03:09.473684210 Avg Losing Trade Duration 1 days 02:46:21.818181818 Profit Factor 1.255718 Expectancy 75.967687 Sharpe Ratio 0.797792 Calmar Ratio 1.192962 Omega Ratio 1.06282 Sortino Ratio 1.220586 dtype: object
InĀ [13]:
pf = vbt.Portfolio.from_signals(btc_price['Close'], short_entries=entries, short_exits=exits, max_size=1, init_cash=100000)
pf.plot().show()
InĀ [14]:
pf.stats()
Out[14]:
Start 2022-12-31 16:00:00+00:00 End 2023-08-30 15:00:00+00:00 Period 242 days 00:00:00 Start Value 100000.0 End Value 95441.2 Total Return [%] -4.5588 Benchmark Return [%] 63.84671 Max Gross Exposure [%] 0.0 Total Fees Paid 0.0 Max Drawdown [%] 7.118069 Max Drawdown Duration 230 days 01:00:00 Total Trades 41 Total Closed Trades 41 Total Open Trades 0 Open Trade PnL 0.0 Win Rate [%] 53.658537 Best Trade [%] 4.904259 Worst Trade [%] -17.68695 Avg Winning Trade [%] 1.652528 Avg Losing Trade [%] -3.321955 Avg Winning Trade Duration 1 days 01:54:32.727272727 Avg Losing Trade Duration 1 days 11:03:09.473684210 Profit Factor 0.682218 Expectancy -111.190244 Sharpe Ratio -1.131724 Calmar Ratio -0.954699 Omega Ratio 0.914696 Sortino Ratio -1.523115 dtype: object